import React from 'react';
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
import {cn} from '@/lib/utils';
import {useTooltipLifecycle} from '@/hooks/core';

// Tooltip内容组件 - 针对不同按钮的背景色样式
const TooltipContent = React.forwardRef<
    React.ElementRef<typeof TooltipPrimitive.Content>,
    React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content> & {
    variant?: 'drag' | 'delete' | 'edit' | 'copy' | 'info';
}
>(({className, sideOffset = 4, variant = 'edit', ...props}, ref) => (
    <TooltipPrimitive.Content
        ref={ref}
        sideOffset={sideOffset}
        className={cn(
            'z-[9999] overflow-hidden rounded-md px-2 py-1 text-xs font-medium text-white shadow-lg',
            'animate-in fade-in-0 duration-150 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:duration-150',
            // 根据按钮类型设置对应的背景色，与按钮悬浮色保持一致
            variant === 'drag' && 'bg-gray-600',
            variant === 'delete' && 'bg-red-500',
            variant === 'edit' && 'bg-primary-600',
            variant === 'copy' && 'bg-success-600',
            // 信息提示样式：小字体灰白色背景
            variant === 'info' && 'bg-gray-100 text-gray-800 text-xs shadow-sm',
            className
        )}
        {...props}
    >
        {props.children}
        <TooltipPrimitive.Arrow
            className={cn(
                // 箭头颜色与背景匹配，使用fill而不是text
                variant === 'drag' && 'fill-gray-600',
                variant === 'delete' && 'fill-red-500',
                variant === 'edit' && 'fill-primary-600',
                variant === 'copy' && 'fill-success-600',
                // 信息提示箭头颜色
                variant === 'info' && 'fill-gray-100'
            )}
        />
    </TooltipPrimitive.Content>
));
TooltipContent.displayName = TooltipPrimitive.Content.displayName;

// Tooltip提供者组件
const TooltipProvider = TooltipPrimitive.Provider;

// Tooltip根组件
const TooltipRoot = TooltipPrimitive.Root;

// Tooltip触发器组件
const TooltipTrigger = TooltipPrimitive.Trigger;

// 简化使用的Tooltip组件
interface TooltipProps {
    children: React.ReactNode;
    content: string;
    side?: 'top' | 'right' | 'bottom' | 'left';
    delayDuration?: number;
    variant?: 'drag' | 'delete' | 'edit' | 'copy' | 'info';
    className?: string;
    // disabled: 为 true 时完全不渲染 Tooltip（直接返回 children）
    disabled?: boolean;
    // closeOnTriggerLeave: 鼠标离开触发按钮是否立刻关闭（默认 true）
    // 说明：Radix Tooltip 默认在指针进入内容区域时保持打开；
    //       业务需要在离开按钮即关闭，无论指针是否移动到 Tooltip 内容上。
    //       利用 Radix 的 disableHoverableContent 实现该行为。
    closeOnTriggerLeave?: boolean;

    // 受控开关（可选）
    open?: boolean;
    onOpenChange?: (open: boolean) => void;

    // 是否在“窗口/标签页生命周期事件”上自动关闭（默认 true）
    autoCloseOnWindowChange?: boolean;
}

const Tooltip: React.FC<TooltipProps> = ({
    children,
    content,
    side = 'top',
    delayDuration = 0,
    variant = 'edit',
    className,
    disabled = false,
    closeOnTriggerLeave = true,
    open: openProp,
    onOpenChange,
    autoCloseOnWindowChange = true,
}) => {
    // 受控/非受控合并
    const isControlled = openProp !== undefined;
    const [internalOpen, setInternalOpen] = React.useState(false);
    const mergedOpen = isControlled ? (openProp as boolean) : internalOpen;
    const setOpenMerged = React.useCallback(
        (next: boolean) => {
            onOpenChange?.(next);
            if (!isControlled) setInternalOpen(next);
        },
        [isControlled, onOpenChange]
    );

    // 用于"强制重挂 TooltipRoot"的键值（彻底清理 Radix 内部 presence/portal 状态）
    const [lifecycleBumpKey, setLifecycleBumpKey] = React.useState(0);

    // 生命周期关闭处理函数：关闭 Tooltip 并重挂组件
    const handleLifecycleClose = React.useCallback(() => {
        setOpenMerged(false);
        // 通过更新 key 让 <TooltipRoot key=...> 全量重建，清空内部状态
        setLifecycleBumpKey((k) => k + 1);
    }, [setOpenMerged]);

    // 使用统一的生命周期管理 Hook（仅在启用时注册）
    useTooltipLifecycle(handleLifecycleClose, autoCloseOnWindowChange && !disabled);

    return (
        <TooltipRoot
            key={lifecycleBumpKey}                  // ← 新增：关键！生命周期事件触发时强制重挂
            open={disabled ? false : mergedOpen}    // ← 修复：禁用时强制关闭，但保持组件结构
            onOpenChange={disabled ? undefined : setOpenMerged}  // ← 修复：禁用时不响应状态变化
            delayDuration={delayDuration}
            // 鼠标一旦离开触发器就关闭，不允许悬停在内容上保持
            disableHoverableContent={closeOnTriggerLeave}
        >
            <TooltipTrigger asChild>{children}</TooltipTrigger>
            {!disabled && (  // ← 修复：仅在启用时渲染Portal，保持组件结构稳定
                <TooltipPrimitive.Portal>
                    <TooltipContent
                        side={side}
                        variant={variant}
                        className={className}
                        // 边界碰撞检测配置，确保 Tooltip 始终在视窗内显示
                        collisionPadding={16}
                        avoidCollisions
                        // 自动调整策略，当空间不足时自动翻转到对面
                        sticky="partial"
                        sideOffset={5}
                    >
                        {content}
                    </TooltipContent>
                </TooltipPrimitive.Portal>
            )}
        </TooltipRoot>
    );
};

export {
    Tooltip,
    TooltipProvider,
    TooltipRoot,
    TooltipTrigger,
    TooltipContent
};
